/*!
 * Ext JS Library 3.3.0
 * Copyright(c) 2006-2010 Ext JS, Inc.
 * licensing@extjs.com
 * http://www.extjs.com/license
 */
/** 
 * @class Ext.ux.grid.filter.DateFilter
 * @extends Ext.ux.grid.filter.Filter
 * Filter by a configurable Ext.menu.DateMenu
 * <p><b><u>Example Usage:</u></b></p>
 * <pre><code>    
var filters = new Ext.ux.grid.GridFilters({
	...
	filters: [{
		// required configs
		type: 'date',
		dataIndex: 'dateAdded',

		// optional configs
		dateFormat: 'm/d/Y',  // default
		beforeText: 'Before', // default
		afterText: 'After',   // default
		onText: 'On',         // default
		pickerOpts: {
			// any DateMenu configs
		},

		active: true // default is false
	}]
});
 * </code></pre>
 */
Ext.ux.grid.filter.DateFilter = Ext.extend(Ext.ux.grid.filter.Filter, {
	/**
	 * @cfg {String} afterText
	 * Defaults to 'After'.
	 */
	afterText : 'After',
	/**
	 * @cfg {String} beforeText
	 * Defaults to 'Before'.
	 */
	beforeText : 'Before',
	/**
	 * @cfg {Object} compareMap
	 * Map for assigning the comparison values used in serialization.
	 */
	compareMap : {
		before: 'lt',
		after:  'gt',
		on:     'eq'
	},
	/**
	 * @cfg {String} dateFormat
	 * The date format to return when using getValue.
	 * Defaults to 'm/d/Y'.
	 */
	dateFormat : 'm/d/Y',

	/**
	 * @cfg {Date} maxDate
	 * Allowable date as passed to the Ext.DatePicker
	 * Defaults to undefined.
	 */
	/**
	 * @cfg {Date} minDate
	 * Allowable date as passed to the Ext.DatePicker
	 * Defaults to undefined.
	 */
	/**
	 * @cfg {Array} menuItems
	 * The items to be shown in this menu
	 * Defaults to:<pre>
	 * menuItems : ['before', 'after', '-', 'on'],
	 * </pre>
	 */
	menuItems : ['before', 'after', '-', 'on'],

	/**
	 * @cfg {Object} menuItemCfgs
	 * Default configuration options for each menu item
	 */
	menuItemCfgs : {
		selectOnFocus: true,
		width: 125
	},

	/**
	 * @cfg {String} onText
	 * Defaults to 'On'.
	 */
	onText : 'On',

	/**
	 * @cfg {Object} pickerOpts
	 * Configuration options for the date picker associated with each field.
	 */
	pickerOpts : {},

	/**
	 * @private
	 * Template method that is to initialize the filter and install required menu items.
	 */
	init : function (config) {
		var menuCfg, i, len, item, cfg, Cls;

		menuCfg = Ext.apply(this.pickerOpts, {
			minDate: this.minDate,
			maxDate: this.maxDate,
			format:  this.dateFormat,
			listeners: {
				scope: this,
				select: this.onMenuSelect
			}
		});

		this.fields = {};
		for (i = 0, len = this.menuItems.length; i < len; i++) {
			item = this.menuItems[i];
			if (item !== '-') {
				cfg = {
					itemId: 'range-' + item,
					text: this[item + 'Text'],
					menu: new Ext.menu.DateMenu(
						Ext.apply(menuCfg, {
							itemId: item
						})
					),
					listeners: {
						scope: this,
						checkchange: this.onCheckChange
					}
				};
				Cls = Ext.menu.CheckItem;
				item = this.fields[item] = new Cls(cfg);
			}
			//this.add(item);
			this.menu.add(item);
		}
	},

	onCheckChange : function () {
		this.setActive(this.isActivatable());
		this.fireEvent('update', this);
	},

	/**
	 * @private
	 * Handler method called when there is a keyup event on an input
	 * item of this menu.
	 */
	onInputKeyUp : function (field, e) {
		var k = e.getKey();
		if (k == e.RETURN && field.isValid()) {
			e.stopEvent();
			this.menu.hide(true);
			return;
		}
	},

	/**
	 * Handler for when the menu for a field fires the 'select' event
	 * @param {Object} date
	 * @param {Object} menuItem
	 * @param {Object} value
	 * @param {Object} picker
	 */
	onMenuSelect : function (menuItem, value, picker) {
		var fields = this.fields,
			field = this.fields[menuItem.itemId];

		field.setChecked(true);

		if (field == fields.on) {
			fields.before.setChecked(false, true);
			fields.after.setChecked(false, true);
		} else {
			fields.on.setChecked(false, true);
			if (field == fields.after && fields.before.menu.picker.value < value) {
				fields.before.setChecked(false, true);
			} else if (field == fields.before && fields.after.menu.picker.value > value) {
				fields.after.setChecked(false, true);
			}
		}
		this.fireEvent('update', this);
	},

	/**
	 * @private
	 * Template method that is to get and return the value of the filter.
	 * @return {String} The value of this filter
	 */
	getValue : function () {
		var key, result = {};
		for (key in this.fields) {
			if (this.fields[key].checked) {
				result[key] = this.fields[key].menu.picker.getValue();
			}
		}
		return result;
	},

	/**
	 * @private
	 * Template method that is to set the value of the filter.
	 * @param {Object} value The value to set the filter
	 * @param {Boolean} preserve true to preserve the checked status
	 * of the other fields.  Defaults to false, unchecking the
	 * other fields
	 */
	setValue : function (value, preserve) {
		var key;
		for (key in this.fields) {
			if(value[key]){
				this.fields[key].menu.picker.setValue(value[key]);
				this.fields[key].setChecked(true);
			} else if (!preserve) {
				this.fields[key].setChecked(false);
			}
		}
		this.fireEvent('update', this);
	},

	/**
	 * @private
	 * Template method that is to return <tt>true</tt> if the filter
	 * has enough configuration information to be activated.
	 * @return {Boolean}
	 */
	isActivatable : function () {
		var key;
		for (key in this.fields) {
			if (this.fields[key].checked) {
				return true;
			}
		}
		return false;
	},

	/**
	 * @private
	 * Template method that is to get and return serialized filter data for
	 * transmission to the server.
	 * @return {Object/Array} An object or collection of objects containing
	 * key value pairs representing the current configuration of the filter.
	 */
	getSerialArgs : function () {
		var args = [];
		for (var key in this.fields) {
			if(this.fields[key].checked){
				args.push({
					type: 'date',
					comparison: this.compareMap[key],
					value: this.getFieldValue(key).format(this.dateFormat)
				});
			}
		}
		return args;
	},

	/**
	 * Get and return the date menu picker value
	 * @param {String} item The field identifier ('before', 'after', 'on')
	 * @return {Date} Gets the current selected value of the date field
	 */
	getFieldValue : function(item){
		return this.fields[item].menu.picker.getValue();
	},

	/**
	 * Gets the menu picker associated with the passed field
	 * @param {String} item The field identifier ('before', 'after', 'on')
	 * @return {Object} The menu picker
	 */
	getPicker : function(item){
		return this.fields[item].menu.picker;
	},

	/**
	 * Template method that is to validate the provided Ext.data.Record
	 * against the filters configuration.
	 * @param {Ext.data.Record} record The record to validate
	 * @return {Boolean} true if the record is valid within the bounds
	 * of the filter, false otherwise.
	 */
	validateRecord : function (record) {
		var key,
			pickerValue,
			val = record.get(this.dataIndex);

		if(!Ext.isDate(val)){
			return false;
		}
		val = val.clearTime(true).getTime();

		for (key in this.fields) {
			if (this.fields[key].checked) {
				pickerValue = this.getFieldValue(key).clearTime(true).getTime();
				if (key == 'before' && pickerValue <= val) {
					return false;
				}
				if (key == 'after' && pickerValue >= val) {
					return false;
				}
				if (key == 'on' && pickerValue != val) {
					return false;
				}
			}
		}
		return true;
	}
});